const router = require('koa-router')();
const cc = require('../conCtl');
const js = require('../jsCtl');
const db = require('../dbCtl');
const pc = require('../projectCtl');

const schedule = require('node-schedule');



const storeLotterySchedule = {
  item: {}
};
/** 
 * 系统启动，初始化待开奖活动
 */
(async () => {
  await pc.initSettings();//初始化环境变量
  //1查询所有已上线且未结束活动
  //2遍历活动
  //3构建定时器
  var myDate = new Date();
  var mytime = js.format_datetime(myDate);
  let data = await db.model('t_gameLottery').where('state>1 && dt2>=?', mytime).orderBy('dt1').select();

  for (let index = 0; index < data.length; index++) {
    setTimeLottery(data[index].id);
  }
})();

//开奖函数
const setTimeLottery = async (id) => {
  //获取活动数据
  let data = await db.model('t_gameLottery').where('id=?', id).shift('未找到活动');
  //清除现有定时器
  if (storeLotterySchedule.item[id]) {
    clearInterval(storeLotterySchedule.item[id]);
  }

  //获取活动开奖的时间
  var date = new Date(data.dt2);
  //创建定时器
  storeLotterySchedule.item[id] = schedule.scheduleJob(date, () => {
    console.log('开始抽奖当前时间:', date);
    lottery(id);
  });
};

var AsyncLock = require('async-lock');
const { now } = require('moment');
var lock = new AsyncLock();
//开奖方法
const lottery = async gameid => {
  return new Promise(async (r) => {
    await lock.acquire('gameLotteryRun:' + gameid, async () => {

      db.startTransaction(async (tran) => {
        let prizesArray = [];//开奖奖品序列

        //获取活动数据
        let game = await tran.model('t_gameLottery').where('id=?', gameid).shift('未找到活动');

        //判断状态是否能开奖
        let stateStr =
          game.state == 0 && '已删除' ||
          game.state == 1 && '未上线' ||
          game.state == 3 && '已结束' || '';
        if (stateStr) js.throwObj(`该活动处于"${stateStr}"状态，不能执行开奖！`);

        //-------------------执行开奖---------------------
        //获取奖票总数
        let circulation = game.circulation;
        //获取购票总数
        let ticketCount = await tran.model('t_gameLottery_ticket').where('game_id=?', gameid).count('购票');
        //获取奖品列表
        let prizes = await tran.model('t_gameLottery_prize').where('game_id=?', gameid).orderBy('prize_level, dt').select();

        let robot_winner_list = "";
        for (let i = 0; i < prizes.length; i++) {//遍历所有奖品
          let elem = prizes[i];
          for (let j = 0; j < elem.show_amount; j++) {//按奖品的显示数量遍历
            let prize = js.regroup(elem, ['game_id', 'goods_id', 'prize_level']);//先构建奖品

            //如果是实际开奖
            if (j >= elem.amount) {
              //查找内定人员
              let winnerTel = '';
              if (elem.winner_te) {

                let winners = elem.winner_tel.split(',');

                //如果存在内定人员，则指定该奖品为内定人员获得（多个内定人员按顺序i指派）
                winnerTel = winners[j] || '';
                if (winnerTel) {
                  let winnerTicket = await tran.model('t_users a')
                    .join('t_gameLottery_ticket b on a.openid=b.openid')
                    .field('a.openid, b.id')
                    .where('a.tel=? && b.status=1', winnerTel).shift();
                  if (winnerTicket) {
                    prize.winnerType = 1;//设置中奖人类型为内定
                    prize.winnerOpenid = winnerTicket.openid;
                    prize.ticket_id = winnerTicket.id;
                    prizesArray.push(prize);//奖品对象压入待开奖序列
                    await tran.model('t_gameLottery_winner').insertOrUpdate(prize);//入库
                    await tran.model('t_gameLottery_ticket').where('id=?', prize.ticket_id).update({ status: 0, goods_id: prize.goods_id });//修改奖票使用状态

                    ticketCount -= ticketCount;
                    continue;//遍历下一个奖品
                  }
                }
              }
              //没有找到内定获奖人,随机抽奖
              let winI = js.randomNum(1, circulation);
              if (winI <= ticketCount) {//查询中奖人
                let winnerData = await tran.model('t_gameLottery_ticket').where('game_id=?&&status=1', gameid).select(winI, 1);
                if (winnerData.length) {
                  let winnerTicket = winnerData[0];
                  prize.winnerType = 2;//设置中奖人类型为随机
                  prize.winnerOpenid = winnerTicket.openid;
                  prize.ticket_id = winnerTicket.id;
                  prizesArray.push(prize);//奖品对象压入待开奖序列
                  await tran.model('t_gameLottery_winner').insertOrUpdate(prize);//入库
                  await tran.model('t_gameLottery_ticket').where('id=?', prize.ticket_id).update({ status: 0, goods_id: prize.goods_id });//修改奖票使用状态

                  //生成用户订单
                  await tran.model('t_order').insert({ game_id: gameid, goods_id: prize.goods_id, openid: prize.winnerOpenid, type: 2, state: 2 });
                  ticketCount -= ticketCount;
                  continue;//遍历下一个奖品
                }
              }
            }
            //无人中奖 或者 虚拟开奖
            //随机获得一个机器人
            let robot = await pc.createRobot(robot_winner_list);
            if (robot) {
              prize.winnerType = 3;//设置中奖人类型为机器人
              prize.winnerOpenid = robot.id;
              robot_winner_list += robot.id + ",";
              robot_winner_list = robot_winner_list.substr(0,robot_winner_list.length-1);
              prizesArray.push(prize);//奖品对象压入待开奖序列
              await tran.model('t_gameLottery_winner').insertOrUpdate(prize);//入库
              await tran.model('t_robot_winner').insert({ robot_id: robot.id, type: 2, about_id: prize.game_id, goods_id: prize.goods_id });//入库
              continue;
            } else {
              //机器人好像出问题了，只能设置无人中奖
              prize.winnerType = 0;//设置中奖人类型为无
              prize.winnerOpenid = '';
              prizesArray.push(prize);//奖品对象压入待开奖序列
              await tran.model('t_gameLottery_winner').insertOrUpdate(prize);//入库
            }
          }
        }

        //更新活动状态
        await tran.model('t_gameLottery').where('id=?', gameid).update({ state: 3 });

        //插入中奖信息通知
        await tran.start("INSERT INTO t_message (openid, type, title, message)( " +
          "SELECT a.openid, 1 AS 'type', b.`name` AS title, c.`name` AS message " +
          "FROM t_gameLottery_ticket a " +
          "LEFT JOIN t_gameLottery b ON a.game_id = b.id " +
          "LEFT JOIN t_goods c ON a.goods_id = c.id " +
          "WHERE a.`status` = 0 AND a.game_id = ?)", gameid);
        //插入未中奖信息通知
        await tran.start("INSERT INTO t_message (openid, type, title)( " +
          "SELECT a.openid, 1 AS 'type', b.`name` AS title " +
          "FROM t_gameLottery_ticket a " +
          "LEFT JOIN t_gameLottery b ON a.game_id = b.id " +
          "WHERE a.`status` = 1 AND a.game_id = ?)", gameid);

        r(prizesArray);
        delete storeLotterySchedule.item[gameid];//删除当前定期活动缓存
        console.log('开奖完成当前时间:', new Date());
      });
      return;
    });
  });
};

/**
@hostpath = http://127.0.0.1/service/gameLottery
 */

/** 获取定期抽奖活动列表
###
    GET {{hostpath}}?page=1&size=30
### */
router.get('/', async c => {
  let
    page = c.query.page || 1,
    size = c.query.size || 30;

  let data = await db.model('t_gameLottery')
    .where('state>0')
    .orderBy('dt1')
    .select(page, size);
  cc.send_list(c, data);
});

/** 创建活动/编辑活动
###
### */
router.put('/', async c => {
  js.check_params(
    !c.request.body.name && '!名称' ||
    !c.request.body.dt1 && '!开始时间' ||
    !c.request.body.dt2 && '!结束时间' ||
    !c.request.body.price && '!奖票价格' ||
    !c.request.body.circulation && '!发行量' ||
    !c.request.body.img && '!banner');

  let data = c.request.body;

  if (!c.request.body.id) {
    delete data.id;
  } else {
    let state = await db.model('t_gameLottery').where('id=?', data.id).shift('', 'state');
    if (state == 2) js.throwObj('进行中的定期抽奖活动不允许修改');
  }
  let id = await db.model('t_gameLottery')
    .insertOrUpdate(data);

  //todo........开奖代码
  setTimeLottery(id);

  cc.send(c,id);
});

/** 
 * 删除活动
 */
router.del('/', async c => {
  js.check_params(!c.request.body.id && '!活动ID');

  let data = c.request.body;

  let state = await db.model('t_gameLottery').where('id=?', data.id).shift('未找到指定对象', 'state');
  if (state == 2)
    js.throwObj('进行中的活动不可删除', js.rescode.fail);

  await db.model('t_gameLottery').where('id=?', data.id).relyUpdate('删除失败', {
    state: 0
  });

  cc.send(c);
});

/** 
 * 上线
 */
router.post('/upline', async c => {
  js.check_params(!c.request.body.id && '!活动ID');

  await db.model('t_gameLottery').where('id=?', c.request.body.id).relyUpdate('上线失败', { state: 2 });

  //todo.......定时开奖代码
  setTimeLottery(c.request.body.id);


  cc.send(c);
});

/** 手动停止
###
### */
router.post('/stop', async c => {
  js.check_params(!c.request.body.id && '!活动ID');
  //修改定期抽奖活动状态
  await db.model('t_gameLottery').where('id=?', c.request.body.id).relyUpdate('停止失败', { state: 4 });
  //初始化缓存
  delete storeLotterySchedule.item[c.request.body.id];
  cc.send(c);
});

/**
 * 查询中奖人
###
    GET {{hostpath}}/reward/4
###
 */
router.get('/reward/:id', async c => {
  let data = await db.start('select z.*, x.`name` as goodName from ( ' +
    'select a.prize_level, a.goods_id, b.nick, b.headurl,a.winnerType from t_gameLottery_winner a left join t_users b on a.winnerOpenid=b.openid where a.game_id=? and (a.winnerType=1 or a.winnerType=2) ' +
    'UNION ' +
    'select a.prize_level, a.goods_id, b.nick, b.headurl,a.winnerType from t_gameLottery_winner a left join t_robot b on a.winnerOpenid=b.id where a.game_id=? and a.winnerType=3 ' +
    'UNION ' +
    'select a.prize_level, a.goods_id, "无人中奖" as "nick", "" as headurl,a.winnerType from t_gameLottery_winner a left join t_users b on a.winnerOpenid=b.openid where a.game_id=? and a.winnerType=0 ' +
    ') z join t_goods x on z.goods_id=x.id ' +
    'order by prize_level', [c.params.id, c.params.id, c.params.id]);
  cc.send(c, data);

});

/** 开奖
###
### */
router.post('/lottery', async (c, e) => {
  js.check_params(!c.request.body.id && '!活动ID');
  let data = await lottery(c.request.body.id);
  cc.send(c, data);
});

/***************************************************** 活动奖品 ************************************************************/


/** 获取活动奖品列表
###
    GET {{hostpath}}/list?page=1&size=30
### */
router.get('/prize', async c => {
  js.check_params(!c.query.id && '!活动ID');

  let data = await db.model('t_gameLottery_prize a').join('t_goods b on a.goods_id=b.id')
    .where('a.game_id=?&&b.state>0', c.query.id)
    .orderBy('a.prize_level, a.dt')
    .select();
  cc.send_list(c, data);
});

/** 添加奖品
###
### */
router.put('/prize', async c => {
  js.check_params(
    !c.request.body.game_id && '!活动ID' ||
    !c.request.body.goods_id && '!奖品ID' ||
    !c.request.body.prize_level && '!奖品等级');

  let data = c.request.body;
  delete data.id;

  await db.startTransaction(async (tran) => {
    await tran.model('t_goods').where('id=? && repertory_type=0', data.goods_id).update({ state: 2 });//只更新库存类型为0的商品（单件商品）
    await tran.model('t_gameLottery_prize').insertOrUpdate(data);
  });

  cc.send(c);
});

/** 删除奖品
###
### */
router.del('/prize', async c => {
  js.check_params(
    !c.request.body.game_id && '!活动ID' ||
    !c.request.body.goods_id && '!奖品ID' ||
    !c.request.body.prize_level && '!奖品等级');

  let data = c.request.body;

  await db.startTransaction(async (tran) => {
    await tran.model('t_goods').where('id=? && repertory_type=0', data.goods_id).update({ state: 1 });//只更新库存类型为0的商品（单件商品），无限库存商品的state始终为1
    await tran.model('t_gameLottery_prize').where('game_id=?&&goods_id=?&&prize_level=?', data.game_id, data.goods_id, data.prize_level).delete();
  });

  cc.send(c);
});


/** 内定中奖设置
###
### */
router.post('/prizeWinner', async c => {
  js.check_params(
    !c.request.body.game_id && '!活动ID' ||
    !c.request.body.goods_id && '!奖品ID');

  let data = c.request.body;
  data.winner_tel = data.winner_tel || '';

  await db.model('t_gameLottery_prize').where('game_id=? && goods_id=?', data.game_id, data.goods_id).relyUpdate('内定失败', { winner_tel: data.winner_tel });

  cc.send(c);
});

module.exports = router;